package com.mars.admin.modules.post.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.mars.admin.modules.post.dto.PostWithUserDTO;
import com.mars.admin.modules.post.entity.*;
import com.mars.admin.modules.post.mapper.*;
import com.mars.admin.modules.post.service.IPostService;
import com.mars.admin.modules.post.service.ITopicService;
import com.mars.admin.modules.post.vo.PostInfoVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

import static com.mars.admin.modules.post.entity.table.PostTableDef.POST;

/**
 * 帖子服务实现类
 *
 * @author Mars
 * @version 1.0
 * @date 2025-01-07
 */
@Slf4j
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements IPostService {

    @Autowired
    private PostMapper postMapper;

    @Autowired
    private PostTopicMapper postTopicMapper;

    @Autowired
    private PostLikeMapper postLikeMapper;

    @Autowired
    private PostCollectMapper postCollectMapper;

    @Autowired
    private PostShareMapper postShareMapper;

    @Autowired
    private PostViewMapper postViewMapper;

    @Autowired
    private PostCommentMapper postCommentMapper;

    @Autowired
    private ITopicService topicService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishPost(Post post, List<Long> topicIds) {
        try {
            // 设置默认值
            if (post.getViewCount() == null) {
                post.setViewCount(0);
            }
            if (post.getLikeCount() == null) {
                post.setLikeCount(0);
            }
            if (post.getCommentCount() == null) {
                post.setCommentCount(0);
            }
            if (post.getShareCount() == null) {
                post.setShareCount(0);
            }
            if (post.getCollectCount() == null) {
                post.setCollectCount(0);
            }
            if (post.getIsTop() == null) {
                post.setIsTop(0);
            }
            if (post.getIsHot() == null) {
                post.setIsHot(0);
            }
            if (post.getIsRecommend() == null) {
                post.setIsRecommend(0);
            }
            if (post.getVisibility() == null) {
                post.setVisibility(1);
            }
            if (post.getAllowComment() == null) {
                post.setAllowComment(1);
            }
            if (post.getStatus() == null) {
                post.setStatus(0);  // 修改为待审核状态
            }
            if (post.getAuditStatus() == null) {
                post.setAuditStatus(0);
            }
            if (post.getIsOriginal() == null) {
                post.setIsOriginal(1);
            }
            post.setUserId(StpUtil.getLoginIdAsLong());
            // 保存帖子
            boolean saved = save(post);
            if (!saved) {
                return false;
            }

            // 关联话题
            if (!CollectionUtils.isEmpty(topicIds)) {
                for (Long topicId : topicIds) {
                    PostTopic postTopic = new PostTopic();
                    postTopic.setPostId(post.getId());
                    postTopic.setTopicId(topicId);
                    postTopic.setCreateTime(LocalDateTime.now());
                    postTopicMapper.insert(postTopic);

                    // 更新话题帖子数量
                    topicService.updateTopicStats(topicId, 1, 0);
                }
            }

            return true;
        } catch (Exception e) {
            log.error("发布帖子失败，帖子信息：{}，话题ID列表：{}", post, topicIds, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePost(Post post, List<Long> topicIds) {
        try {
            post.setUpdateTime(LocalDateTime.now());
            boolean updated = updateById(post);
            if (!updated) {
                return false;
            }

            // 删除原有话题关联
            postTopicMapper.deleteByPostId(post.getId());

            // 重新关联话题
            if (!CollectionUtils.isEmpty(topicIds)) {
                for (Long topicId : topicIds) {
                    PostTopic postTopic = new PostTopic();
                    postTopic.setPostId(post.getId());
                    postTopic.setTopicId(topicId);
                    postTopic.setCreateTime(LocalDateTime.now());
                    postTopicMapper.insert(postTopic);
                }
            }

            return true;
        } catch (Exception e) {
            log.error("更新帖子失败，帖子信息：{}，话题ID列表：{}", post, topicIds, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePost(Long postId) {
        try {
            // 删除帖子
            boolean deleted = removeById(postId);
            if (!deleted) {
                return false;
            }

            // 删除相关数据
            postTopicMapper.deleteByPostId(postId);
            postLikeMapper.deleteByPostId(postId);
            postCollectMapper.deleteByPostId(postId);
            postShareMapper.deleteByPostId(postId);
            postViewMapper.deleteByPostId(postId);
            postCommentMapper.deleteByPostId(postId);

            return true;
        } catch (Exception e) {
            log.error("删除帖子失败，帖子ID：{}", postId, e);
            throw e;
        }
    }

    @Override
    public Page<Post> getPostsByUserId(Long userId, Page<Post> page) {
        return postMapper.selectPostListByUserId(userId, page);
    }

    @Override
    public Page<Post> getPostsByTopicId(Long topicId, Page<Post> page) {
        return postMapper.selectByTopicId(topicId, page);
    }

    @Override
    public Page<Post> getHotPosts(Page<Post> page) {
        return postMapper.selectHotPosts(page);
    }

    @Override
    public Page<Post> getRecommendPosts(Page<Post> page) {
        return postMapper.selectRecommendPosts(page);
    }

    @Override
    public Page<Post> getFollowingPosts(Long userId, Page<Post> page) {
        return postMapper.selectFollowingPosts(userId, page);
    }

    @Override
    public Page<Post> getPostsByRegion(Long regionId, Page<Post> page) {
        return postMapper.selectByRegion(regionId, page);
    }

    @Override
    public Page<Post> searchPosts(String keyword, Page<Post> page) {
        return postMapper.searchPosts(keyword, page);
    }

    @Override
    public Page<Post> getCollectedPosts(Long userId, Page<Post> page) {
        return postMapper.selectCollectedPosts(userId, page);
    }

    @Override
    public Page<Post> getLikedPosts(Long userId, Page<Post> page) {
        return postMapper.selectLikedPosts(userId, page);
    }

    @Override
    public Page<Post> getPendingAuditPosts(Page<Post> page) {
        return postMapper.selectPendingAuditPosts(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditPost(Long postId, Integer auditStatus, String auditReason, Long auditUserId) {
        try {
            Post post = new Post();
            post.setId(postId);
            post.setAuditStatus(auditStatus);
            post.setAuditReason(auditReason);
            post.setAuditUserId(auditUserId);
            post.setAuditTime(LocalDateTime.now());
            post.setUpdateTime(LocalDateTime.now());

            // 如果审核通过，设置状态为已发布
            if (auditStatus == 1) {
                post.setStatus(1);
            }

            return updateById(post);
        } catch (Exception e) {
            log.error("审核帖子失败，帖子ID：{}，审核状态：{}，审核原因：{}", postId, auditStatus, auditReason, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean likePost(Long postId, Long userId) {
        try {
            // 检查是否已点赞
            PostLike existingLike = postLikeMapper.selectByPostIdAndUserId(postId, userId);
            if (existingLike != null) {
                return false;
            }

            // 创建点赞记录
            PostLike postLike = new PostLike();
            postLike.setPostId(postId);
            postLike.setUserId(userId);
            postLike.setCreateTime(LocalDateTime.now());

            boolean inserted = postLikeMapper.insert(postLike) > 0;
            if (inserted) {
                // 更新帖子点赞数
                postMapper.updatePostStats(postId, 0, 1, 0, 0, 0);
            }

            return inserted;
        } catch (Exception e) {
            log.error("点赞帖子失败，帖子ID：{}，用户ID：{}", postId, userId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unlikePost(Long postId, Long userId) {
        try {
            boolean deleted = postLikeMapper.deleteByPostIdAndUserId(postId, userId) > 0;
            if (deleted) {
                // 更新帖子点赞数
                postMapper.updatePostStats(postId, 0, -1, 0, 0, 0);
            }
            return deleted;
        } catch (Exception e) {
            log.error("取消点赞帖子失败，帖子ID：{}，用户ID：{}", postId, userId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean collectPost(Long postId, Long userId) {
        try {
            // 检查是否已收藏
            PostCollect existingCollect = postCollectMapper.selectByPostIdAndUserId(postId, userId);
            if (existingCollect != null) {
                return false;
            }

            // 创建收藏记录
            PostCollect postCollect = new PostCollect();
            postCollect.setPostId(postId);
            postCollect.setUserId(userId);
            postCollect.setCreateTime(LocalDateTime.now());

            boolean inserted = postCollectMapper.insert(postCollect) > 0;
            if (inserted) {
                // 更新帖子收藏数
                postMapper.updatePostStats(postId, 0, 0, 0, 0, 1);
            }

            return inserted;
        } catch (Exception e) {
            log.error("收藏帖子失败，帖子ID：{}，用户ID：{}", postId, userId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean uncollectPost(Long postId, Long userId) {
        try {
            boolean deleted = postCollectMapper.deleteByPostIdAndUserId(postId, userId) > 0;
            if (deleted) {
                // 更新帖子收藏数
                postMapper.updatePostStats(postId, 0, 0, 0, 0, -1);
            }
            return deleted;
        } catch (Exception e) {
            log.error("取消收藏帖子失败，帖子ID：{}，用户ID：{}", postId, userId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sharePost(Long postId, Long userId, Integer platform, String content, String shareIp) {
        try {
            // 创建分享记录
            PostShare postShare = new PostShare();
            postShare.setPostId(postId);
            postShare.setUserId(userId);
            postShare.setPlatform(platform);
            postShare.setContent(content);
            postShare.setShareIp(shareIp);
            postShare.setCreateTime(LocalDateTime.now());

            boolean inserted = postShareMapper.insert(postShare) > 0;
            if (inserted) {
                // 更新帖子分享数
                postMapper.updatePostStats(postId, 0, 0, 0, 1, 0);
            }

            return inserted;
        } catch (Exception e) {
            log.error("分享帖子失败，帖子ID：{}，用户ID：{}", postId, userId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean recordPostView(Long postId, Long userId, String visitorIp, String userAgent, String referer) {
        try {
            // 创建浏览记录
            PostView postView = new PostView();
            postView.setPostId(postId);
            postView.setUserId(userId);
            postView.setVisitorIp(visitorIp);
            postView.setUserAgent(userAgent);
            postView.setReferer(referer);
            postView.setCreateTime(LocalDateTime.now());

            boolean inserted = postViewMapper.insert(postView) > 0;
            if (inserted) {
                // 更新帖子浏览数
                postMapper.updatePostStats(postId, 1, 0, 0, 0, 0);
            }

            return inserted;
        } catch (Exception e) {
            log.error("记录帖子浏览失败，帖子ID：{}，用户ID：{}", postId, userId, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setPostTop(Long postId, Integer isTop) {
        try {
            Post post = new Post();
            post.setId(postId);
            post.setIsTop(isTop);
            post.setUpdateTime(LocalDateTime.now());
            return updateById(post);
        } catch (Exception e) {
            log.error("设置帖子置顶状态失败，帖子ID：{}，置顶状态：{}", postId, isTop, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setPostHot(Long postId, Integer isHot) {
        try {
            Post post = new Post();
            post.setId(postId);
            post.setIsHot(isHot);
            post.setUpdateTime(LocalDateTime.now());
            return updateById(post);
        } catch (Exception e) {
            log.error("设置帖子热门状态失败，帖子ID：{}，热门状态：{}", postId, isHot, e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setPostRecommend(Long postId, Integer isRecommend) {
        try {
            Post post = new Post();
            post.setId(postId);
            post.setIsRecommend(isRecommend);
            post.setUpdateTime(LocalDateTime.now());
            return updateById(post);
        } catch (Exception e) {
            log.error("设置帖子推荐状态失败，帖子ID：{}，推荐状态：{}", postId, isRecommend, e);
            throw e;
        }
    }

    @Override
    public Page<PostInfoVO> getPostListWithUser(Page<PostInfoVO> page,
            Long userId,
            Long topicId,
            Integer postType,
            Integer isHot,
            Integer isRecommend,
            Integer status,
            Integer auditStatus, String keyword) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        if (userId != null) {
            queryWrapper.eq("user_id", userId);
        }
        if (topicId != null) {
            queryWrapper.eq("topic_id", topicId);
        }
        if (postType != null) {
            queryWrapper.eq("post_type", postType);
        }
        if (isHot != null) {
            queryWrapper.eq("is_hot", isHot);
        }
        if (isRecommend != null) {
            queryWrapper.eq("is_recommend", isRecommend);
        }
        if (status != null) {
            queryWrapper.eq("status", status);
        }
        if (auditStatus != null) {
            queryWrapper.eq("audit_status", auditStatus);
        }
        if (keyword != null) {
            queryWrapper.and(POST.TITLE.like(keyword).or(POST.CONTENT.like(keyword)));
        }
        queryWrapper.orderBy("create_time", false);

        return postMapper.paginateWithRelationsAs(page,queryWrapper, PostInfoVO.class);
//        return postMapper.selectPostListWithUser(page, userId, topicId, postType, isHot, isRecommend, status,
//                auditStatus);
    }

    @Override
    public PostInfoVO getDetail(Long id) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(POST.ID.eq(id));
        PostInfoVO postdetail = postMapper.selectOneWithRelationsByQueryAs(queryWrapper, PostInfoVO.class);
        return postdetail;
    }
}
